#include "VxIrrLib.h"
#include "time.h"

U32							g_u32SysTimeSec = 0;			// unix time stamp.. seconds since jan 1, 1970
U32							g_u32ElapsedTimeMs = 0;			// elapsed time ( app alive time ) milliseconds
U64							g_u64SysTimeMs = 0;				// system time in milliseconds
U64							g_u64StartupTimeMs = 0;			// unix time in milliseconds of first update ( application start )
static irr::core::stringc	g_strAssetPath;
SoundMgr					g_oSndMgr;				// sound manager

//============================================================================
#ifdef WIN_PLATFORM
// create gettimeofday function that acts like the unix version
	#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
	  #define DELTA_EPOCH_IN_MICROSECS  11644473600000000Ui64
	#else
	  #define DELTA_EPOCH_IN_MICROSECS  11644473600000000ULL
	#endif

	struct timezone 
	{
		int  tz_minuteswest; /* minutes W of Greenwich */
		int  tz_dsttime;     /* type of dst correction */
	};
	 
	int gettimeofday(struct timeval *tv, struct timezone *tz)
	{
		FILETIME ft;
		unsigned __int64 tmpres = 0;
		static int tzflag;

		if (NULL != tv)
		{
			GetSystemTimeAsFileTime(&ft);

			tmpres |= ft.dwHighDateTime;
			tmpres <<= 32;
			tmpres |= ft.dwLowDateTime;

			/*converting file time to unix epoch*/
			tmpres -= DELTA_EPOCH_IN_MICROSECS; 
			tmpres /= 10;  /*convert into microseconds*/
			tv->tv_sec = (long)(tmpres / 1000000UL);
			tv->tv_usec = (long)(tmpres % 1000000UL);
		}

		if (NULL != tz)
		{
			if (!tzflag)
			{
				_tzset();
				tzflag++;
			}
			//tz->tz_minuteswest = _timezone / 60;
			//tz->tz_dsttime = _daylight;
		}
		return 0;
	}
#endif //WIN_PLATFORM 


//============================================================================
//! Update system time
void	UpdateSystemTime( void )
{
    struct timeval  now;
    gettimeofday(&now, NULL);
	if( 0 == g_u64StartupTimeMs )
	{
		g_u64StartupTimeMs = (now.tv_sec*1000 + now.tv_usec / 1000);
	}
    g_u32SysTimeSec = now.tv_sec;
    g_u64SysTimeMs = (now.tv_sec*1000 + now.tv_usec / 1000);
	g_u32ElapsedTimeMs = (U32)(g_u64SysTimeMs - g_u64StartupTimeMs);
}

//============================================================================
//! set root path game assets are located at
void SetGameAssetPath( const char * pFileName )
{
	g_strAssetPath = pFileName;
}
//============================================================================
//! get root path game assets are located at
irr::core::stringc	GetGameAssetPath( void )
{
	return g_strAssetPath;
}

//============================================================================
//! append asset file name and path together and return path + filename 
irr::core::stringc	GetAssetPathAndName( const char * pFileName, EGameAssetType eAssetType )
{
	irr::core::stringc strPathAndName = g_strAssetPath;
	switch( eAssetType )
	{
	case eGameAssetTypeGeneric:
		break;
	case eGameAssetTypeSound:
		strPathAndName += "sounds/";
		break;
	case eGameAssetTypeMesh:
		strPathAndName += "meshes/";
		break;
	case eGameAssetTypeTexture:
		strPathAndName += "textures/";
		break;
	case eGameAssetTypeMaterial:
		strPathAndName += "materials/";
		break;
	case eGameAssetTypeShader:
		strPathAndName += "shaders/";
		break;
	case eGameAssetTypeAI:
		strPathAndName += "ai/";
		break;
	case eGameAssetTypeScript:
		strPathAndName += "scripts/";
		break;
	case eGameAssetTypeSave:
		strPathAndName += "saves/";
		break;
	case eGameAssetTypeGui:
		strPathAndName += "gui/";
		break;
	case eGameAssetTypeScene:
		strPathAndName += "scenes/";
		break;
	case eGameAssetTypeLevel:
		strPathAndName += "levels/";
		break;
	case eGameAssetTypeCampaign:
		strPathAndName += "campaigns/";
		break;
	case eGameAssetTypeCollide:
		strPathAndName += "collide/";
		break;
	default:
		vx_assert( false );
	}
	return strPathAndName + pFileName;
}
